package org.traffometer.traffosim;

import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;
import org.uispec4j.Button;
import org.uispec4j.Panel;
import org.uispec4j.TextBox;
import org.uispec4j.Trigger;
import org.uispec4j.UISpec4J;
import org.uispec4j.interception.WindowInterceptor;


/**
 * Uses UiSpec4J to test the functionality of the configuration wizard.
 *  
 * @author George Lee
 */
public class TestConfigWizardUi {
  static {
    UISpec4J.init();
  }
  
  /**Panel containing the ConfigWizard.*/
  private Panel configPanel;
  
  /**Individual components of the window.*/
  private Button addPacket;
  private Button saveConfig;
  
  private TextBox batchRate;
  
  private TextBox startLat;
  private TextBox startLng;
  private TextBox startTime;
  
  private TextBox endLat;
  private TextBox endLng;
  private TextBox endTime;
  
  private TextBox vehicle;
  
  /**Status messages from the ConfigWizardUi.*/
  private String status;

  /**
   * Test normal operation of using the ConfigWizard.
   */
  @Test
  public void testNormalOperation() {
    //Add data to the individual text boxes.
    this.batchRate.setText("1");
    
    this.startLat.setText("33.2998");
    this.startLng.setText("42.2425");
    this.startTime.setText("198492");
    
    this.endLat.setText("33.78723");
    this.endLng.setText("41.8842");
    this.endTime.setText("199297");
    
    this.vehicle.setText("foo");
    
    //Add packet.
    this.addPacket.click();
    this.status = "Number of packets to send: 1";
    boolean hasCorrectState = this.configPanel.containsLabel(this.status).isTrue();
    assertTrue("Testing addition of a packet.", hasCorrectState);
    
    //Save configuration.
    this.saveConfig.click();
    this.status = "Configuration file saved to lib/config/gui-test.cfg";
    hasCorrectState = this.configPanel.containsLabel(status).isTrue();
    assertTrue("Testing save of configuration.", hasCorrectState);
  }
  
  /**
   * Test passing bad data to the GUI.
   */
  @Test
  public void testBadParameter() {
    //Add data to the individual text boxes.
    this.batchRate.setText("1");
    
    //Bad data.
    this.startLat.setText("bar");
    this.startLng.setText("42.2425");
    this.startTime.setText("198492");
    
    this.endLat.setText("33.78723");
    this.endLng.setText("41.8842");
    this.endTime.setText("199297");
    
    this.vehicle.setText("foo");
    
    //Attempt to add packet.
    this.addPacket.click();
    this.status = "Error in parsing data to create packet.";
    boolean hasCorrectState = this.configPanel.containsLabel(this.status).isTrue();
    assertTrue("Testing addition of bad data.", hasCorrectState);
  }
  
  /**
   * Test passing bad data to the batch rate.
   */
  @Test
  public void testBadRate() {
    //Try passing invalid string.
    this.batchRate.setText("foo");

    //Attempt to save configuration.
    this.saveConfig.click();
    this.status = "Error parsing batch rate.";
    boolean hasCorrectState = this.configPanel.containsLabel(this.status).isTrue();
    assertTrue("Testing save of bad batch rate.", hasCorrectState);
    
    //Try passing negative number.
    this.batchRate.setText("-1");
    
    //Attempt to save configuration.
    this.saveConfig.click();
    this.status = "Error, batch rate must be nonnegative.";
    hasCorrectState = this.configPanel.containsLabel(this.status).isTrue();
    assertTrue("Testing save of negative batch rate.", hasCorrectState);
  }
  
  /**
   * Start up ConfigWizard for UiSpec4J and get the individual components.
   * 
   * @throws Exception if there is an error.
   */
  @Before
  public void setUp() throws Exception {
    this.configPanel = WindowInterceptor.run(new Trigger() {
      /**
       * Start the ConfigWizardUi.
       */
      public void run() {
        Main.main(new String[] {"-ui", "ConfigWizard"});
      }
    }); 
    
    //Set up fields and buttons.
    this.addPacket = this.configPanel.getButton("Add Packet");
    this.saveConfig = this.configPanel.getButton("Save Config");
    
    this.batchRate = this.configPanel.getTextBox("BatchRate");
    
    this.startLat = this.configPanel.getTextBox("StartLat");
    this.startLng = this.configPanel.getTextBox("StartLng");
    this.startTime = this.configPanel.getTextBox("StartTime");
    
    this.endLat = this.configPanel.getTextBox("EndLat");
    this.endLng = this.configPanel.getTextBox("EndLng");
    this.endTime = this.configPanel.getTextBox("EndTime");
    
    this.vehicle = this.configPanel.getTextBox("VehicleName");
  }
}
